package se.ytterman.jserial.jni;

import java.lang.*;
import java.util.*;

import se.ytterman.jserial.io.CommunicationAdapter;

public class SerialInterface implements CommunicationAdapter {

    /*****************************************************************/
    /* Define constants                                              */
    /*****************************************************************/

    // Define baudrates
    // XXX There may be a need to define higher baud-rates,
    // for exmaple for HSDPA modems...
    public static final int BAUD_500000  = 500000;
    public static final int BAID_460800  = 460800;
    public static final int BAUD_230400  = 230400;
    public static final int BAUD_115200  = 115200;
    public static final int BAUD_57600   =  57600;
    public static final int BAUD_38400   =  38400;
    public static final int BAUD_19200   =  19200;
    public static final int BAUD_9600    =   9600;
    public static final int BAUD_4800    =   4800;
    public static final int BAUD_2400    =   2400;
    public static final int BAUD_1800    =   1800;
    public static final int BAUD_1200    =   1200;
    public static final int BAUD_600     =    600;
    public static final int BAUD_300     =    300;
    public static final int BAUD_200     =    200;
    public static final int BAUD_150     =    150;
    public static final int BAUD_134     =    134;
    public static final int BAUD_110     =    110;
    public static final int BAUD_75      =     75;
    public static final int BAUD_50      =     50;
    public static final int BAUD_U       =     -1;

    // Define parity
    public static final int PARITY_NO    =      0;
    public static final int PARITY_ODD   =      1;
    public static final int PARITY_EVEN  =      2;
    public static final int PARITY_MARK  =      3;
    public static final int PARITY_SPACE =     4;
    public static final int PARITY_U     =     -1;

    // Define databits
    public static final int DATA_8BITS   =      8;
    public static final int DATA_7BITS   =      7;
    public static final int DATA_6BITS   =      6;
    public static final int DATA_5BITS   =      5;
    public static final int DATA_UBITS   =     -1;
    
    // Define stopbits
    public static final int STOP_1BITS   =      1;
    public static final int STOP_2BITS   =      2;
    public static final int STOP_UBITS   =     -1;

    /*****************************************************************/
    /* Accessors                                                     */
    /*****************************************************************/

    // getName
    public String getDeviceName() {
	return this.device_name;
    }

    // getDescription
    public String getDescription() {
	String description = "N/A";

	return description;
    }

    public int getSpeed() {
	return this.device_speed;
    }

    public int getParity() {
	return this.device_parity;
    }
     
    public int getDatabits() {
	return this.device_databits;
    }
 
    public int getStopbits() {
	return this.device_stopbits;
    }

    // Check if the device is available
    public boolean isAvailable() {
	return this.available;
    }

    // Check if the device is open
    public boolean isOpen() {
	return this.open;
    }    

    // toString
    public String toString() {
	String result = ""; 
	
	if(this.open && this.available) {
	    result = this.device_name + " (" + 
		     this.device_fd + "), Open:" +
		     this.open + " Available:" +
		     this.available + " [ Speed:" +
		     this.device_speed + " Databits:" +
		     this.device_databits + " Parity:" +
		     this.device_parity + " Stopbits:" +
		     this.device_stopbits + " ]";
	}
	else {
	    result = this.device_name + " (" + 
		     this.device_fd + "), Open:" +
		     this.open + " Available:" +
		     this.available;
	}

	return result;
    }    

    // toDocument
    public String toDocument() {
	return "XXX";
    }

    /*****************************************************************/
    /* Native mutators                                               */
    /*****************************************************************/

    public native void setSpeed(int bauds);
 
    public native void setParity(int parity);
     
    public native void setDatabits(int databits);
 
    public native void setStopbits(int stopbits);

    // Read from serial interface (native)
    public native byte[] read();

    // Write to serial interface (native)
    public native void write(byte[] data);

    // Close socket (native)
    public native void close();

    /*****************************************************************/

    // Protected constructor used by JNI factory
    private SerialInterface() {
	this.device_speed = BAUD_38400;
	this.device_parity = PARITY_NO;
	this.device_databits = DATA_8BITS;
	this.device_stopbits = STOP_1BITS;
    }

    /*****************************************************************/
    /* Storage                                                       */
    /*****************************************************************/    

    // Device name
    private String device_name;

    // File descriptor used to communicate with device
    private int device_fd;

    // 
    private int device_speed;

    private int device_parity;

    private int device_databits;

    private int device_stopbits;

    // Is open flag
    private boolean open;

    // Is available flag
    private boolean available;
}
